tomcat运行一段时间之后出现文件句柄数过多的情况,java.net.SocketException: Too many open files
网上解决方法
A couple of days ago we ran into the infamous “too many open files” when our Tomcat web server was under load.
There are several blogs around the internet that tries to deal with this issue but none of them seemed to do the trick for us. Usually what you do is to set the ulimit to a greater value (it’s something like 1024 by default). But in order to make it permanent after reboot the first thing suggested is to update the /proc/sys/fs/file-max file and increase the value then edit the /etc/security/limits.conf and add the following line * - nofile 2048 (see here for more details). But none of this worked for us. We saw that when doing
1 | cat /proc/<tomcat pid>/limits |
the limit was still set to the initial value of 1024:
1 | Limit Soft Limit Hard Limit Units |
It was not until we found this thread that the reason and solution became clear. Our Tomcat instance was started as a service during boot and there’s a bug discovered and filed (with patch) in 2005 that doesn’t seem to have been resolved yet. The bug reveals itself by ignoring the max number of open files limit when starting daemons in Ubuntu/Debain. So the work-around suggested by “BOK” was to edit /etc/init.d/tomcat and add:
1 | ulimit -Hn 16384 |
Finally the max number of open files for Tomcat was increased!
分析
打开的文件过多,一般来说是由于应用程序对资源使用不当造成,比如没有及时关闭Socket或数据库连接等。但也可能应用确实需要打开比较多的文件句柄,而系统本身的设置限制了这一数量。
Tomcat将主动打开尽可能多的文件句柄,并将硬限制设置为如此高的数量将导致有问题的虚拟机可以消耗大量内存。
1
2
3
4
5查看系统允许打开的最大文件数
cat /proc/sys/fs/file-max
tomcat文件句柄数
cat /proc/<tomcat pid>/limits不仅要关注系统最大文件句柄数,还要关注tomcat启动能使用的最大句柄数。
在I/O操作之后需要在finally里调用close()。